/*
 * OPIAM Suite
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package opiam.admin.faare.service.services;

import opiam.admin.faare.MessageUtil;
import opiam.admin.faare.PropertiesManager;
import opiam.admin.faare.config.javabeans.JBClassDescriptor;
import opiam.admin.faare.config.javabeans.JBFieldDescriptor;
import opiam.admin.faare.exception.PersistenceException;
import opiam.admin.faare.exception.ServiceException;
import opiam.admin.faare.persistence.LdapUtil;
import opiam.admin.faare.service.UserContext;

import org.apache.log4j.Logger;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;


/**
 * Generic sort service.
 *
 */
public final class SortService extends Service
{
    /** Instance of logger. */
    private static Logger _logger = Logger.getLogger(SortService.class.getName());

    /** Instance of service. */
    private static SortService _instance = new SortService();

    /** Attribute to sort on one attribute. */
    private static JBFieldDescriptor _fieldDesc = null;

    //DW/2594/BeginPatch

    /** Attributes to sort on several attributes. */
    private static JBFieldDescriptor[] _fieldDescs = null;

    //DW/2594/EndPatch

    /** Utility class. */
    private SortService()
    {
    }

    /**
     * Initialization method of the service.
     *
     * @param directory  Configuration directory
     *
     * @see Service.initialize().
     *
     * @throws ServiceException required by upper class, not used here.
     */
    public static void initialize(final String directory)
        throws ServiceException
    {
        //DW/2655/BeginPatch
        //SortService.setServiceEnabled(true);
        _instance.setServiceEnabled(true);
        //DW/2655/EndPatch

    }

    //DW/2655/BeginPatch
    /**
     * This method indicates if the service is active or not.
     *
     * @return True if it is active, false otherwise.
     */
    public static boolean isServiceEnabled()
    {
        return _instance.serviceEnabled;
    }
    //DW/2655/EndPatch

    /**
     * This method executes the sort.<br>
     * The first argument contains the set of the objects to sort
     * (JavaBeans inheriting from opiam.admin.faare.persistence.javabeans.JBTop).<br>
     * The third argument is the field name of the JavaBean object on which to execute the sort.
     *
     * @param list  Objects to sort.
     * @param cls   Class of objects to sort.
     * @param att   Name of the sorting attribute.
     * @param userContext  Context of the user.
     *
     * @throws ServiceException error
     */
    public static void sort(final List list, final Class cls, final String att,
        final UserContext userContext) throws ServiceException
    {
        if (!SortService.isServiceEnabled())
        {
            throw new ServiceException(MessageUtil.formatMessage(
                    "MSG_SERVICE_NOT_ENABLED", "SortService"));
        }

        _logger.debug("cls : " + cls.toString());
        _logger.debug("att : " + att);

        Comparator comp = null;

        try
        {
            JBClassDescriptor classDesc = PropertiesManager.getInstance()
                                                           .getPersistenceDescriptionMap()
                                                           .getClassDescriptor(cls.getName());

            _fieldDesc = classDesc.getFieldDescriptor(att);

            comp = new Comparator()
                    {
                        @Override
						public int compare(final Object o1, final Object o2)
                        {
                            try
                            {
                                if ((LdapUtil.getFieldValue(_fieldDesc, o1) != null) &&
                                        (LdapUtil.getFieldValue(_fieldDesc, o2) != null))
                                {
                                    return ((String) LdapUtil.getFieldValue(_fieldDesc,
                                        o1)).trim().compareToIgnoreCase(((String) LdapUtil.getFieldValue(
                                            _fieldDesc, o2)).trim());
                                }
                                else
                                {
                                    return -1;
                                }
                            }
                            catch (PersistenceException e)
                            {
                                return -1;
                            }
                        }
                    };
        }
        catch (PersistenceException pe)
        {
            _logger.error(pe.getMessage());

            if (_logger.isDebugEnabled())
            {
                _logger.debug("Trace", pe);
            }

            throw new ServiceException(pe.getMessage(), pe);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        Collections.sort(list, comp);
    }

    //DW/2594/BeginPatch

    /**
     * This method executes the sort.<br>
     * The first argument contains the set of the objects to sort
     * (JavaBeans inheriting from opiam.admin.faare.persistence.javabeans.JBTop).<br>
     * The second argument is the objects class to sort
     * The third argument is the fields names list of the JavaBean object on which to execute the sort.
     *
     * @param list  Objects to sort.
     * @param cls   Class of objects to sort.
     * @param atts  Set of the sorting attributes.
     * @param userContext  Context of the user.
     *
     * @throws ServiceException - if error occurs or the service is disable.
     */
    public static void sort(final List list, final Class cls,
        final String[] atts, final UserContext userContext)
        throws ServiceException
    {
        if (!SortService.isServiceEnabled())
        {
            throw new ServiceException(MessageUtil.formatMessage(
                    "MSG_SERVICE_NOT_ENABLED", "SortService"));
        }

        _logger.debug("cls : " + cls.toString());

        Comparator comp = null;

        try
        {
            JBClassDescriptor classDesc = PropertiesManager.getInstance()
                                                           .getPersistenceDescriptionMap()
                                                           .getClassDescriptor(cls.getName());

            _fieldDescs = new JBFieldDescriptor[atts.length];

            for (int i = 0; i < atts.length; i++)
            {
                _fieldDescs[i] = classDesc.getFieldDescriptor(atts[i]);
            }

            comp = new Comparator()
                    {
                        @Override
						public int compare(final Object o1, final Object o2)
                        {
                            int ret = 0;
                            int idx = 0;

                            try
                            {
                                while ((ret == 0) && (idx < atts.length))
                                {
                                    if ((LdapUtil.getFieldValue(
                                                _fieldDescs[idx], o1) != null) &&
                                            (LdapUtil.getFieldValue(
                                                _fieldDescs[idx], o2) != null))
                                    {
                                        ret = ((String) LdapUtil.getFieldValue(_fieldDescs[idx],
                                                o1)).trim().compareToIgnoreCase(((String) LdapUtil.getFieldValue(
                                                    _fieldDescs[idx], o2)).trim());
                                    }
                                    else
                                    {
                                        ret = -1;
                                    }

                                    idx++;
                                }

                                return ret;
                            }
                            catch (PersistenceException e)
                            {
                                return -1;
                            }
                        }
                    };
        }
        catch (PersistenceException pe)
        {
            _logger.error(pe.getMessage());

            if (_logger.isDebugEnabled())
            {
                _logger.debug("Trace", pe);
            }

            throw new ServiceException(pe.getMessage(), pe);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        Collections.sort(list, comp);
    }

    //DW/2594/EndPatch
}
